package com.dingwen.frame.controller.base.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dingwen.frame.constant.ITipAndMessage;
import com.dingwen.frame.constant.ValidationGroups;
import com.dingwen.frame.controller.base.IBaseController;
import com.dingwen.frame.dto.BaseDto;
import com.dingwen.frame.vo.Result;
import com.dingwen.frame.vo.ResultGenerator;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.groups.Default;
import java.io.Serializable;
import java.util.List;

/**
 * 基础 crud 封装 controller
 * 在最新版本springboot中出现范型类无法注入错误，将实现类修改为抽象类解决
 * <p>
 *
 * @author dingwen
 * @date 2021.06.29 15:09
 * @since 1.0.0-SNAPSHOT
 */
public abstract class BaseControllerImpl<T extends Serializable> implements IBaseController<T> {

    /**
     * base service
     */
    private final IService<T> iService;

    @Autowired
    public BaseControllerImpl(IService<T> iService) {
        this.iService = iService;
    }


    @Override
    @ApiOperation("根据主键查询")
    @ApiImplicitParam(value = "主键", name = "id")
    @GetMapping("/{id}")
    public Result find(@PathVariable(value = "id") Serializable id) {
        return ResultGenerator.genOkResult(iService.getById(id));
    }


    @Override
    @ApiOperation("根据主键集合查询")
    @ApiImplicitParam(value = "主键List集合", name = "ids", dataType = "body")
    @GetMapping("/ids")
    public Result find(@RequestParam(value = "ids", required = false) List<Serializable> ids) {
        return ResultGenerator.genOkResult(iService.listByIds(ids));
    }

    @Override
    public Result find(boolean flag) {
        return ResultGenerator.genOkResult(flag ? iService.list() : iService.listMaps());
    }


    @Override
    @ApiOperation("综合查询")
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "pageSize", value = "页面大小"),
                    @ApiImplicitParam(name = "pageNum", value = "页码数"),
                    @ApiImplicitParam(name = "flag", value = "true: List<T> false: List<Map<String,Object>>")
            }
    )
    @GetMapping("")
    public Result find(@RequestParam(name = "pageSize", required = false) Integer pageSize,
                       @RequestParam(name = "pageNum", required = false) Integer pageNum,
                       @RequestParam(name = "flag", defaultValue = "true") boolean flag) {

        // 页面大小或者页码数为空则查询所有列表
        if (ObjectUtils.isEmpty(pageNum) || ObjectUtils.isEmpty(pageSize)) {
            return find(flag);
        }
        IPage<T> iPage = new Page<>(pageNum, pageSize);
        return ResultGenerator.genOkResult(iService.page(iPage));
    }


    @Override
    @ApiOperation("获取数据表总记录条数")
    @GetMapping("/count")
    public Result count() {
        return ResultGenerator.genOkResult(iService.count());
    }


    @Override
    @ApiOperation("修改数据表单条记录")
    @PutMapping("")
    public Result modify(T t) {
        boolean updateByIdResult = iService.updateById(t);
        return updateByIdResult ? ResultGenerator.genOkResult() : ResultGenerator.genFailureResult(ITipAndMessage.MODIFY_FAIL);
    }

    @PutMapping("/batch")
    @Override
    @ApiOperation("批量修改")
    @ApiImplicitParam(name = "baseDto", value = "实体Json对象集合")
    public Result modify(@RequestBody BaseDto<T> baseDto) {
        boolean updateBatchByIdResult = iService.updateBatchById(baseDto.getTList());
        return updateBatchByIdResult ? ResultGenerator.genOkResult() : ResultGenerator.genFailureResult(ITipAndMessage.SAVE_FAIL);
    }

    @PostMapping("/batch")
    @Override
    @ApiOperation("批量添加")
    @ApiImplicitParam(name = "baseDto", value = "条件集合Json对象")
    public Result save(@RequestBody BaseDto<T> baseDto) {
        boolean saveBatchResult = iService.saveBatch(baseDto.getTList());
        return saveBatchResult ? ResultGenerator.genOkResult() : ResultGenerator.genFailureResult(ITipAndMessage.SAVE_FAIL);
    }

    @Override
    @ApiOperation("保存一个对象到数据库")
    @ApiImplicitParam(value = "实体", name = "t", dataType = "body")
    @PostMapping("")
    public Result save(@RequestBody @Validated({ValidationGroups.Save.class, Default.class}) T t) {
        boolean saveResult = iService.save(t);
        return saveResult ? ResultGenerator.genOkResult() : ResultGenerator.genFailureResult(ITipAndMessage.SAVE_FAIL);
    }


    @Override
    @ApiOperation("删除单条记录")
    @ApiImplicitParam(name = "id", value = "主键")
    @DeleteMapping("/id")
    public Result remove(@RequestParam(value = "id") Serializable id) {
        boolean removeByIdResult = iService.removeById(id);
        return removeByIdResult ? ResultGenerator.genOkResult() : ResultGenerator.genFailureResult(ITipAndMessage.REMOVE_FAIL);
    }

    @ApiOperation("批量删除记录")
    @ApiImplicitParam(name = "ids", value = "主键集合")
    @DeleteMapping("/batch")
    @Override
    public Result remove(@RequestParam("ids") List<Serializable> ids) {
        boolean removeByIdsResult = iService.removeByIds(ids);
        return removeByIdsResult ? ResultGenerator.genOkResult() : ResultGenerator.genFailureResult(ITipAndMessage.REMOVE_FAIL);
    }
}
